home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-2.iso / os2 / rsynth1.zip / holmes.c < prev    next >
Text File  |  1995-12-19  |  11KB  |  469 lines

  1. #include <config.h>
  2. /* $Id: holmes.c,v 1.13 1994/11/08 13:30:50 a904209 Exp a904209 $
  3.  */
  4. char *holmes_id = "$Id: holmes.c,v 1.13 1994/11/08 13:30:50 a904209 Exp a904209 $";
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #include <useconfig.h>
  8. #include <math.h>
  9. #include "proto.h"
  10. #include "nsynth.h"
  11. #include "elements.h"
  12. #include "darray.h"
  13. #include "holmes.h"
  14. #include "phfeat.h"
  15. #include "getargs.h"
  16.  
  17. #if 1
  18. #define AMP_ADJ 14
  19. #else
  20. #define AMP_ADJ 0
  21. #endif
  22.  
  23. FILE *par_file;
  24. FILE *jsru_file;
  25. int speed = 1;
  26.  
  27. double frac = 1.0;
  28.  
  29. typedef struct
  30.  {
  31.   float v;                        /* boundary value */
  32.   int t;                          /* transition time */
  33.  }
  34. slope_t;
  35.  
  36. typedef struct
  37.  {
  38.   slope_t p[nEparm];
  39.  }
  40. trans_t;
  41.  
  42. typedef struct
  43.  {
  44.   float a;
  45.   float b;
  46.   float v;
  47.  }
  48. filter_t, *filter_ptr;
  49.  
  50. static float filter PROTO((filter_ptr p, Float v));
  51.  
  52. static void jsru_save PROTO((double f0, float *tp));
  53.  
  54. static float
  55. filter(p, v)
  56. filter_ptr p;
  57. Float v;
  58. {
  59.  return p->v = (p->a * v + p->b * p->v);
  60. }
  61.  
  62. /* 'a' is dominant element, 'b' is dominated
  63.    ext is flag to say to use external times from 'a' rather
  64.    than internal i.e. ext != 0 if 'a' is NOT current element.
  65.  
  66.  */
  67.  
  68. static void set_trans PROTO((slope_t * t, Elm_ptr a, Elm_ptr b, int ext, int e));
  69.  
  70. static void
  71. set_trans(t, a, b, ext, e)
  72. slope_t *t;
  73. Elm_ptr a;
  74. Elm_ptr b;
  75. int ext;
  76. int e;
  77. {
  78.  int i;
  79.  for (i = 0; i < nEparm; i++)
  80.   {
  81.    t[i].t = ((ext) ? a->p[i].ed : a->p[i].id) * speed;
  82.    if (t[i].t)
  83.     t[i].v = a->p[i].fixd + (a->p[i].prop * b->p[i].stdy) * (float) 0.01;
  84.    else
  85.     t[i].v = b->p[i].stdy;
  86.   }
  87. }
  88.  
  89. static float linear PROTO((Float a, Float b, int t, int d));
  90.  
  91. /*              
  92.    ______________ b
  93.    /
  94.    /
  95.    /
  96.    a____________/                 
  97.    0   d
  98.    ---------------t---------------
  99.  */
  100.  
  101. static float
  102. linear(a, b, t, d)
  103. Float a;
  104. Float b;
  105. int t;
  106. int d;
  107. {
  108.  if (t <= 0)
  109.   return a;
  110.  else if (t >= d)
  111.   return b;
  112.  else
  113.   {
  114.    float f = (float) t / (float) d;
  115.    return (a + (b - a) * f);
  116.   }
  117. }
  118.  
  119. static float interpolate PROTO((char *w, char *p, slope_t * s, slope_t * e, Float mid, int t, int d));
  120.  
  121. static float
  122. interpolate(w, p, s, e, mid, t, d)
  123. char *w;
  124. char *p;
  125. slope_t *s;
  126. slope_t *e;
  127. Float mid;
  128. int t;
  129. int d;
  130. {
  131.  float steady = d - (s->t + e->t);
  132. #ifdef DEBUG
  133.  fprintf(stderr, "%4s %s s=%g,%d e=%g,%d m=%g,%g\n",
  134.          w, p, s->v, s->t, e->v, e->t, mid, steady);
  135. #endif
  136.  if (steady >= 0)
  137.   {
  138.    /* Value reaches stready state somewhere ... */
  139.    if (t < s->t)
  140.     return linear(s->v, mid, t, s->t);    /* initial transition */
  141.    else
  142.     {
  143.      t -= s->t;
  144.      if (t <= steady)
  145.       return mid;                 /* steady state */
  146.      else
  147.       return (linear(mid, e->v, (int) (t - steady), e->t));
  148.      /* final transition */
  149.     }
  150.   }
  151.  else
  152.   {
  153.    float f = (float) 1.0 - ((float) t / (float) d);
  154.    float sp = linear(s->v, mid, t, s->t);
  155.    float ep = linear(e->v, mid, d - t, e->t);
  156.    return (f * sp + ((float) 1.0 - f) * ep);
  157.   }
  158. }
  159.  
  160.  
  161. unsigned
  162. holmes(nelm, elm, nsamp, samp_base)
  163. unsigned nelm;
  164. unsigned char *elm;
  165. unsigned nsamp;
  166. short *samp_base;
  167. {
  168.  filter_t flt[nEparm];
  169.  klatt_frame_t pars;
  170.  short *samp = samp_base;
  171.  Elm_ptr le = &Elements[0];
  172.  unsigned i = 0;
  173.  unsigned tstress = 0;
  174.  unsigned ntstress = 0;
  175.  slope_t stress_s;
  176.  slope_t stress_e;
  177.  float top = 1.1 * def_pars.F0hz10;
  178.  int j;
  179.  pars = def_pars;
  180.  pars.FNPhz = le->p[fn].stdy;
  181.  pars.B1phz = pars.B1hz = 60;
  182.  pars.B2phz = pars.B2hz = 90;
  183.  pars.B3phz = pars.B3hz = 150;
  184. #if 0
  185.  pars.F4hz = 3500;
  186. #endif
  187.  pars.B4phz = def_pars.B4phz;
  188.  
  189.  /* flag new utterance */
  190.  parwave_init(&klatt_global);
  191.  
  192.  /* Set stress attack/decay slope */
  193.  stress_s.t = 40;
  194.  stress_e.t = 40;
  195.  stress_e.v = 0.0;
  196.  
  197.  for (j = 0; j < nEparm; j++)
  198.   {
  199.    flt[j].v = le->p[j].stdy;
  200.    flt[j].a = frac;
  201.    flt[j].b = (float) 1.0 - (float) frac;
  202.   }
  203.  while (i < nelm)
  204.   {
  205.    Elm_ptr ce = &Elements[elm[i++]];
  206.    unsigned dur = elm[i++];
  207.    i++; /* skip stress */
  208.    /* Skip zero length elements which are only there to affect
  209.       boundary values of adjacent elements
  210.     */
  211.    if (dur > 0)
  212.     {
  213.      Elm_ptr ne = (i < nelm) ? &Elements[elm[i]] : &Elements[0];
  214.      slope_t start[nEparm];
  215.      slope_t end[nEparm];
  216.      unsigned t;
  217.  
  218.      if (ce->rk > le->rk)
  219.       {
  220.        if (par_file)
  221.         fprintf(par_file, "# %s < %s\n", le->name, ce->name);
  222.        set_trans(start, ce, le, 0, 's');
  223.        /* we dominate last */
  224.       }
  225.      else
  226.       {
  227.        if (par_file)
  228.         fprintf(par_file, "# %s >= %s\n", le->name, ce->name);
  229.        set_trans(start, le, ce, 1, 's');
  230.        /* last dominates us */
  231.       }
  232.  
  233.      if (ne->rk > ce->rk)
  234.       {
  235.        if (par_file)
  236.         fprintf(par_file, "# %s < %s\n", ce->name, ne->name);
  237.        set_trans(end, ne, ce, 1, 'e');
  238.        /* next dominates us */
  239.       }
  240.      else
  241.       {
  242.        if (par_file)
  243.         fprintf(par_file, "# %s >= %s\n", ce->name, ne->name);
  244.        set_trans(end, ce, ne, 0, 'e');
  245.        /* we dominate next */
  246.       }
  247.  
  248.      if (par_file)
  249.       {
  250.        int j;
  251.        fprintf(par_file, "# %s\n", ce->name);
  252.        for (j = 0; j < nEparm; j++)
  253.         fprintf(par_file, "%c%6s", (j) ? ' ' : '#', Ep_name[j]);
  254.        fprintf(par_file, "\n");
  255.        for (j = 0; j < nEparm; j++)
  256.         fprintf(par_file, "%c%6.4g", (j) ? ' ' : '#', start[j].v);
  257.        fprintf(par_file, "\n");
  258.        for (j = 0; j < nEparm; j++)
  259.         fprintf(par_file, "%c%6d", (j) ? ' ' : '#', start[j].t);
  260.        fprintf(par_file, "\n");
  261.       }
  262.  
  263.      for (t = 0; t < dur; t++, tstress++)
  264.       {
  265.        float base = top * 0.8 ;             /* 3 * top / 5 */
  266.        float tp[nEparm];
  267.        int j;
  268.  
  269.        if (tstress == ntstress)
  270.         {
  271.          unsigned j = i;
  272.          stress_s = stress_e;
  273.          tstress = 0;
  274.          ntstress = dur;
  275. #ifdef DEBUG_STRESS
  276.          printf("Stress %g -> ", stress_s.v);
  277. #endif
  278.          while (j <= nelm)
  279.           {
  280.            Elm_ptr e   = (j < nelm) ? &Elements[elm[j++]] : &Elements[0];
  281.            unsigned du = (j < nelm) ? elm[j++] : 0;
  282.            unsigned s  = (j < nelm) ? elm[j++] : 3;
  283.            if (s || e->feat & vwl)
  284.             {
  285.              unsigned d = 0;
  286.              if (s)
  287.               stress_e.v = (float) s / 3;
  288.              else
  289.               stress_e.v = (float) 0.1;
  290.              do
  291.               {
  292.                d += du;
  293. #ifdef DEBUG_STRESS
  294.                printf("%s", (e && e->dict) ? e->dict : "");
  295. #endif
  296.                e = (j < nelm) ? &Elements[elm[j++]] : &Elements[0];
  297.                du = elm[j++];
  298.               }
  299.              while ((e->feat & vwl) && elm[j++] == s);
  300.              ntstress += d / 2;
  301.              break;
  302.             }
  303.            ntstress += du;
  304.           }
  305. #ifdef DEBUG_STRESS
  306.          printf(" %g @ %d\n", stress_e.v, ntstress);
  307. #endif
  308.         }
  309.  
  310.        for (j = 0; j < nEparm; j++)
  311.         tp[j] = filter(flt + j, interpolate(ce->name, Ep_name[j], &start[j], &end[j], (float) ce->p[j].stdy, t, dur));
  312.  
  313.        /* Now call the synth for each frame */
  314.  
  315.        pars.F0hz10 = base + (top - base) *
  316.         interpolate("", "f0", &stress_s, &stress_e, (float) 0, tstress, ntstress);
  317.  
  318.        pars.AVdb = pars.AVpdb = tp[av];
  319.        pars.AF = tp[af];
  320.        pars.FNZhz = tp[fn];
  321.        pars.ASP = tp[asp];
  322.        pars.Aturb = tp[avc];
  323.        pars.B1phz = pars.B1hz = tp[b1];
  324.        pars.B2phz = pars.B2hz = tp[b2];
  325.        pars.B3phz = pars.B3hz = tp[b3];
  326.        pars.F1hz = tp[f1];
  327.        pars.F2hz = tp[f2];
  328.        pars.F3hz = tp[f3];
  329.        /* AMP_ADJ + is a bodge to get amplitudes up to klatt-compatible levels
  330.           Needs to be fixed properly in tables
  331.         */
  332. /*
  333.    pars.ANP  = AMP_ADJ + tp[an];
  334.  */
  335.        pars.AB = AMP_ADJ + tp[ab];
  336.        pars.A5 = AMP_ADJ + tp[a5];
  337.        pars.A6 = AMP_ADJ + tp[a6];
  338.        pars.A1 = AMP_ADJ + tp[a1];
  339.        pars.A2 = AMP_ADJ + tp[a2];
  340.        pars.A3 = AMP_ADJ + tp[a3];
  341.        pars.A4 = AMP_ADJ + tp[a4];
  342.  
  343.  
  344.        parwave(&klatt_global, &pars, samp);
  345.  
  346.        samp += klatt_global.nspfr;
  347.        if (par_file)
  348.         {
  349.          for (j = 0; j < nEparm; j++)
  350.           fprintf(par_file, " %6.4g", tp[j]);
  351.          fprintf(par_file, "\n");
  352.         }
  353.        if (jsru_file)
  354.         jsru_save(pars.F0hz10 * 0.1, tp);
  355.        /* Declination of f0 envelope 0.25Hz / cS */
  356.       /* top -= 0.5; */
  357.       }
  358.      if (par_file)
  359.       {
  360.        int j;
  361.        for (j = 0; j < nEparm; j++)
  362.         fprintf(par_file, "%c%6.4g", (j) ? ' ' : '#', end[j].v);
  363.        fprintf(par_file, "\n");
  364.        for (j = 0; j < nEparm; j++)
  365.         fprintf(par_file, "%c%6d", (j) ? ' ' : '#', end[j].t);
  366.        fprintf(par_file, "\n");
  367.       }
  368.     }
  369.    le = ce;
  370.   }
  371.  return (samp - samp_base);
  372. }
  373.  
  374. int
  375. init_holmes(argc, argv)
  376. int argc;
  377. char *argv[];
  378. {
  379.  char *par_name = NULL;
  380.  char *jsru_name = NULL;
  381.  argc = getargs("Holmes",argc, argv,
  382.                 "p", "", &par_name,  "Parameter file for plot",
  383.                 "j", "", &jsru_name, "Data for alternate synth (JSRU)",
  384.                 "S", "%d", &speed,   "Speed (1.0 is 'normal')",
  385.                 "K", "%lg", &frac,   "Parameter filter 'fraction'",
  386.                 NULL);
  387.  if (help_only)
  388.   return argc;
  389.  if (par_name)
  390.   {
  391.    par_file = fopen(par_name, "w");
  392.    if (!par_file)
  393.     perror(par_name);
  394.   }
  395.  if (jsru_name)
  396.   {
  397.    jsru_file = fopen(jsru_name, "w");
  398.    if (!jsru_file)
  399.     perror(jsru_name);
  400.   }
  401.  return argc;
  402. }
  403.  
  404. void
  405. term_holmes()
  406. {
  407.  if (par_file)
  408.   fclose(par_file);
  409.  if (jsru_file)
  410.   fclose(jsru_file);
  411. }
  412.  
  413. static int jsru_freq PROTO((Float f, Float base, Float inc));
  414. static int
  415. jsru_freq(f, base, inc)
  416. Float f;
  417. Float base;
  418. Float inc;
  419. {
  420.  int i;
  421.  f = (f - base) / inc;
  422.  i = (int) f;
  423.  if (i >= 64)
  424.   i = 63;
  425.  return i;
  426. }
  427.  
  428. static int jsru_amp PROTO((Float a));
  429. static int
  430. jsru_amp(a)
  431. Float a;
  432. {
  433.  int i = a;
  434.  if (i <= 0)
  435.   i = 1;
  436.  if (i >= 64)
  437.   i = 63;
  438.  return i;
  439. }
  440.  
  441.  
  442. /*          0     1      2      3      4    5
  443.    F1    F2     F3                 FN
  444.    flflim 125.0 550.0 1350.0 3500.0 3500.0 95.0
  445.    fincrm  25.0  50.0   50.0    0.0    0.0  5.0
  446.  */
  447.  
  448. static void
  449. jsru_save(f0, tp)
  450. double f0;
  451. float *tp;
  452. {
  453.  f0 = 16 * (log(f0 / 25.0) / log(2.0)) - 1;
  454.  
  455.  /* fn, alf, f1, a1, f2, a2, f3, a3, ahf, v, f0, m */
  456.  fputc(jsru_freq(tp[fn], 95.0, 5.0), jsru_file);
  457.  fputc(jsru_amp(tp[an]), jsru_file);
  458.  fputc(jsru_freq(tp[f1], 125.0, 25.0), jsru_file);
  459.  fputc(jsru_amp(tp[a1]), jsru_file);
  460.  fputc(jsru_freq(tp[f2], 550.0, 50.0), jsru_file);
  461.  fputc(jsru_amp(tp[a2]), jsru_file);
  462.  fputc(jsru_freq(tp[f3], 1350.0, 50.0), jsru_file);
  463.  fputc(jsru_amp(tp[a3]), jsru_file);
  464.  fputc(jsru_amp(tp[a4]), jsru_file);
  465.  fputc(jsru_amp(tp[av]), jsru_file);
  466.  fputc((int) f0, jsru_file);
  467.  fputc((int) 32, jsru_file);
  468. }
  469.